package com.yt.app.api.action;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import com.yt.app.api.action.base.BaseAction;
import com.yt.app.api.vo.BaseVo;
import com.yt.app.api.vo.ReserveOrderVo;
import com.yt.app.api.vo.ReserveProductVo;
import com.yt.app.api.vo.ToReserveVo;
import com.yt.app.core.interfaces.*;
import com.yt.app.core.model.UserContact;
import com.yt.app.core.model.UserOrder;
import com.yt.app.core.model.UserOrderDetail;
import com.yt.app.core.model.UserReservation;
import com.yt.app.core.utils.Constant;
import com.yt.core.MsgBean;
import com.yt.core.dao.filter.DynamicSQLFilterImpl;
import com.yt.core.dao.filter.QueryFilter;
import com.yt.order.api.interfaces.*;
import com.yt.order.api.model.GroupOrderProduct;
import com.yt.order.api.model.Institution;
import com.yt.order.api.model.OrderInfo;
import com.yt.order.api.model.Product;
import com.yt.order.api.utils.OrderConstants;
import com.yt.util.DateUtils;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import springfox.documentation.annotations.ApiIgnore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Controller
@Api(tags = "08.订单预约")
@RequestMapping("/reserve")
public class ReserveController extends BaseAction{
    private Logger logger = LoggerFactory.getLogger(ReserveController.class);

    @Autowired
    private ProductService productService;
    @Autowired
    private InstitutionService institutionService;
    @Autowired
    private ProductInstitutionService productInstitutionService;
    @Autowired
    private UserOrderService userOrderService;
    @Autowired
    private UserOrderDetailService userOrderDetailService;
    @Autowired
    private OrderNumberService orderNumberService;

    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private GroupOrderService groupOrderService;
    @Autowired
    private GroupOrderProductService groupOrderProductService;
    @Autowired
    private UserReservationService userReservationService;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private UserContactService userContactService;

    @ApiOperation(value="验证信息",notes = "<p>三种预约方式：</p><p>0：通过订单预约(不需要调用此接口)</p><p>1：通过卡号密码预约</p><p>2：通过身份证号和姓名预约</p>", httpMethod = "POST")
    @ApiResponses(value = {@ApiResponse(code = 200,message = "预约商品", response = ReserveProductVo.class)})
    @RequestMapping("/verify")
    public @ResponseBody Object verifyInfo(
            @ApiParam("卡号") @RequestParam(value = "cardNo", required = false) String cardNo,
            @ApiParam("密码") @RequestParam(value = "password", required = false) String password,
            @ApiParam("身份证号") @RequestParam(value = "identify", required = false) String identify,
            @ApiParam("姓名") @RequestParam(value = "name", required = false) String name,
            @ApiParam(value = "预约方式（0：订单，1：卡密，2：身份证姓名）", required = true) @RequestParam(value = "reserveType", required = false, defaultValue = "0") String reserveType,
            @ApiIgnore HttpServletRequest request
    ) {
        MsgBean msgBean = new MsgBean();
        Long uid = BaseVo.getUIDFromHeader(request);
        long currTime = System.currentTimeMillis()/1000;
        List<ReserveProductVo> voList = new ArrayList<ReserveProductVo>();
        if (Constant.RESERVE_TYPE.BY_CARD_PASSWORD.value().equals(reserveType)) {
            if(cardNo.startsWith("A")){
                UserOrderDetail orderDetail = userOrderDetailService.getByCardNoAndPwd(cardNo, password);
                if(orderDetail != null) {
                    UserOrder userOrder = userOrderService.get(orderDetail.getUserOrderId());
                    if(!Constant.ORDER_STATUS.PAID.value().equals(userOrder.getOrderStatus())){
                        return msgBean.failure("订单状态异常！").returnMsg();
                    }
                    ReserveProductVo vo = new ReserveProductVo();
                    vo.setProductId(orderDetail.getProductId());
                    vo.setProductName(orderDetail.getProductName());
                    vo.setStartDate(userOrder.getOrderTime());
                    vo.setEndDate(userOrder.getOrderTime() + 6 * 30 * 60 * 60);
                    vo.setOrderNo(userOrder.getOrderNo());
                    vo.setCardNo(orderDetail.getCardNo());
                    vo.setReserveType(reserveType);
                    vo.setProductImage(orderDetail.getImageFile());
                    vo.setInstitutionId(orderDetail.getInstitutionId());
                    vo.setInstituitonName(orderDetail.getInstitutionName());
                    if(orderDetail.getLeftCount() > 0 && currTime > vo.getStartDate() && currTime < vo.getEndDate()) {
                        vo.setStatus(1);
                    }else{
                        vo.setStatus(0);
                    }
                    voList.add(vo);
                } else {
                    return msgBean.failure("卡号或密码错误，未找到可预约的商品!").returnMsg();
                }
            }else{
                OrderInfo orderInfo = orderInfoService.getByCardNumberAndPwd(cardNo, password);
                if(orderInfo != null){
                    voList.add(toReserveProduct(orderInfo, reserveType));
                } else {
                    return msgBean.failure("卡号或密码错误，未找到可预约的商品!").returnMsg();
                }
            }
        } else if (Constant.RESERVE_TYPE.BY_IDENTIFY_NAME.value().equals(reserveType)) {
            List<OrderInfo> orderInfoList = orderInfoService.getByIdentifyAndName(identify, name);
            if(orderInfoList != null && !orderInfoList.isEmpty()){
                for(OrderInfo orderInfo : orderInfoList){
                    voList.add(toReserveProduct(orderInfo, reserveType));
                }
            }else{
                return msgBean.failure("身份证信息不存在，请核实信息后重试!").returnMsg();
            }
        } else {
            return msgBean.failure("预约类型错误!").returnMsg();
        }
        if(voList == null || voList.isEmpty()){
            return msgBean.failure("无可预约商品").returnMsg();
        }
        //缓存当前验证结果
        cacheService.putCache("RESERVE_VERIFY_" + uid + "_" + reserveType, "1", 0L);
        msgBean.put("products", voList);
        return msgBean.returnMsg();
    }

    @ApiOperation(value="开始预约",notes = "<p><font color=red>reservationId为空时代表第一次预约，此时orderNo,reserveType必传.</font></p>" +
            "<p><font color=red>reservationId不为空时代表改约，此时忽略orderNo,cardNo, reserveType.</font></p>" +
            "<p>三种预约方式：</p><p>0：通过订单预约</p><p>1：通过卡号密码预约</p><p>2：通过身份证号和姓名预约</p>", httpMethod = "POST")
    @ApiResponses(value = {@ApiResponse(code = 200,message = "预约初始数据", response = ToReserveVo.class)})
    @RequestMapping("/toReserve")
    public @ResponseBody  Object reserve(
            @ApiParam(value = "预约ID", required = false) @RequestParam(value = "reservationId", required = false) Long reservationId,
            @ApiParam(value = "订单号", required = false) @RequestParam(value = "orderNo", required = false, defaultValue = "") String orderNo,
            @ApiParam("卡号") @RequestParam(value = "cardNo", required = false, defaultValue = "") String cardNo,
            @ApiParam(value = "预约方式（0：订单，1：卡密，2：身份证姓名）", required = false) @RequestParam(value = "reserveType", required = true, defaultValue = "0") String reserveType,
            @ApiIgnore HttpServletRequest request
    ) {
        //reservationId不为空时，代表改约
        if(reservationId == null){
            if(orderNo == null || "".equals(orderNo) || reserveType == null || "".equals(reserveType)){
                return new MsgBean().failure("订单号(orderNo)和预约方式(reserveType)不能为空!").returnMsg();
            }
        }else{
            UserReservation reservation = userReservationService.get(reservationId);
            orderNo = reservation.getOrderNo();
            reserveType =  reservation.getReserveType();
            cardNo = reservation.getCardNo();
        }
        logger.info("Start to Reserve:reservationId:{},orderNo:{},reserveType:{}, cardNo:{}", reservationId, orderNo, reserveType, cardNo);
        if(Constant.RESERVE_TYPE.BY_ORDER.value().equals(reserveType)){
            return reserveByOrder(orderNo, cardNo, reserveType, reservationId, request).returnMsg();
        }else if(Constant.RESERVE_TYPE.BY_CARD_PASSWORD.value().equals(reserveType)){
            if(orderNo.startsWith("A")){
                return reserveByOrder(orderNo, cardNo, reserveType, reservationId, request).returnMsg();
            }else {
                return reserveByCardAndPassword(orderNo, cardNo, reserveType, reservationId, request).returnMsg();
            }
        }else if(Constant.RESERVE_TYPE.BY_IDENTIFY_NAME.value().equals(reserveType)) {
            return reserveByCardAndPassword(orderNo, cardNo, reserveType, reservationId, request).returnMsg();
        }else{
            return new MsgBean().failure("预约类型错误").returnMsg();
        }
    }

    @ApiOperation(value="预约", httpMethod = "POST")
    @ApiResponses(value = {@ApiResponse(code = 200,message = "预约信息", response = UserReservation.class)})
    @RequestMapping("/reserve")
    public @ResponseBody  Object reserve(
            @ApiParam(value = "预约ID", required = false) @RequestParam(value = "reservationId", required = false) Long reservationId,
            @ApiParam(value = "订单号", required = true) @RequestParam(value = "orderNo", required = true, defaultValue = "0") String orderNo,
            @ApiParam("卡号") @RequestParam(value = "cardNo", defaultValue = "0") String cardNo,
            @ApiParam(value = "机构ID", required = true) @RequestParam(value = "institutionId", required = true, defaultValue = "0") Long institutionId,
            @ApiParam(value = "姓名", required = true) @RequestParam(value = "endUser", required = true) String endUser,
            @ApiParam(value = "身份证号", required = true) @RequestParam(value = "identify", required = true) String identify,
            @ApiParam(value = "性别：女,男", required = true) @RequestParam(value = "sex", required = true) String sex,
            @ApiParam(value = "报告类型：0：电子，1：纸质，2：自取", required = true) @RequestParam(value = "reportType", required = true, defaultValue = "0") String reportType,
            @ApiParam("收件人") @RequestParam(value = "recipient", required = false) String recipient,
            @ApiParam("地址") @RequestParam(value = "address", required = false) String address,
            @ApiParam(value = "手机号", required = true) @RequestParam(value = "mobile", required = true) String mobile,
            @ApiParam("邮箱") @RequestParam(value = "email", required = false) String email,
            @ApiParam(value = "预约日期", required = true) @RequestParam(value = "reseveDate", required = true) String reserveDate,
            @ApiParam(value = "预约类型（0：订单，1：卡密，2：身份证姓名）", required = true) @RequestParam(value = "reserveType", required = true) String reserveType,
            @ApiParam("备注") @RequestParam(value = "comment", required = false) String comment,
            @ApiIgnore HttpServletRequest request
    ){
        MsgBean msgBean = new MsgBean();
        Long uid = BaseVo.getUIDFromHeader(request);
        UserReservation reservation = null;
        if(reservationId != null){
            reservation = userReservationService.get(reservationId);
        }else{
            reservation = new UserReservation();
        }
        reservation.setIdentify(identify);
        reservation.setName(endUser);
        reservation.setSex(sex);

        reservation.setUid(uid);
        reservation.setReportType(reportType);
        reservation.setAddress(address);
        reservation.setMobile(mobile);
        reservation.setRecipient(recipient);
        reservation.setEmail(email);
        reservation.setComment(comment);
        reservation.setOrderNo(orderNo);
        if(orderNo.startsWith("A")){
            UserOrder userOrder = userOrderService.getByOrderNo(orderNo);
            UserOrderDetail userOrderDetail = userOrderDetailService.getByCardNo(cardNo);
            if(userOrder == null || !Constant.ORDER_STATUS.PAID.value().equals(userOrder.getOrderStatus())){
                return msgBean.failure("订单状态有误，请联系客服").returnMsg();
            }
            if(userOrderDetail == null || (reservationId == null && userOrderDetail.getLeftCount() == 0)){
                return msgBean.failure("无可预约的商品！").returnMsg();
            }

            reservation.setInstitutionId(userOrderDetail.getInstitutionId());
            reservation.setInstitutionName(userOrderDetail.getInstitutionName());
            reservation.setProductId(userOrderDetail.getProductId());
            reservation.setProductName(userOrderDetail.getProductName());
            reservation.setProductImage(userOrderDetail.getImageFile());
            reservation.setReserveDate(reserveDate);
            reservation.setReserveType(Constant.RESERVE_TYPE.BY_ORDER.value());
            reservation.setUserOrderId(userOrder.getId());
            reservation.setUserOrderDetailId(userOrderDetail.getId());
            reservation.setReserveStatus(Constant.RESERVATION_STATUS.RESERVING.value());
            reservation.setReserveInstitutionId(institutionId);
            reservation.setReserveInstitutionName(institutionService.get(institutionId).getName());
            reservation.setCardNo(cardNo);
            reservation.setCardPassword(userOrderDetail.getCardPassword());
            userReservationService.saveReservaction(reservation);

        }else {
            OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);

            if (orderInfo == null || (reservationId == null && orderInfo.getBespeaked().equals("1"))) {
                return msgBean.failure("订单状态有误，请联系客服").returnMsg();
            }

            reservation.setInstitutionId(orderInfo.getIdInstitution());
            reservation.setInstitutionName(orderInfo.getInstitutionName());
            reservation.setProductId(orderInfo.getIdProduct());
            reservation.setProductName(orderInfo.getProductName());
            reservation.setReserveDate(reserveDate);
            reservation.setReserveType(Constant.RESERVE_TYPE.BY_CARD_PASSWORD.value());
            reservation.setUserOrderId(0L);
            reservation.setUserOrderDetailId(0L);
            reservation.setReserveInstitutionId(institutionId);
            reservation.setReserveStatus(Constant.RESERVATION_STATUS.RESERVING.value());
            reservation.setReserveInstitutionName(institutionService.get(institutionId).getName());

            reservation.setCardNo(orderInfo.getCardNumber());
            reservation.setCardPassword(orderInfo.getCardPassword());
            userReservationService.saveReservaction(reservation);
        }

        reservation = userReservationService.getByOrderNo(orderNo);
        msgBean.put("data", reservation);
        return msgBean.returnMsg();
    }

    @ApiOperation(value="预约列表", httpMethod = "POST", notes = "当查询未预约列表时， reserveStatus为订单的状态（0：可预约，1：已过期），并且未预约的不提供预约详情查询（因为本质上显示的是订单信息）。")
    @RequestMapping("/list")
    @ApiResponses(value = {@ApiResponse(code = 200,message = "预约信息", response = UserReservation.class)})
    public @ResponseBody  Object reservationList(
            @ApiParam(value = "列表类型：0：未预约，1：已预约，2：已体检", required = true) @RequestParam(value="listType", required = false) String listType,
            @ApiParam("上次最后一个ID") @RequestParam(value = "lastId", required = false, defaultValue = "0") Long lastId,
            @ApiIgnore HttpServletRequest request
    ){
        MsgBean msgBean = new MsgBean();
        Long uid = BaseVo.getUIDFromHeader(request);

        List<UserReservation> reservationList = null;
        if("0".equals(listType)){
            List<UserOrderDetail> orderDetailList = userOrderDetailService.getValidDetailListByUid(uid, lastId, 20);
            if(orderDetailList != null && !orderDetailList.isEmpty()){
                reservationList = new ArrayList<UserReservation>();
                Map<Long, UserOrder> orderMap = new HashMap<Long, UserOrder>();
                for(UserOrderDetail detail : orderDetailList){
                    UserReservation reservation = new UserReservation();
                    reservation.setId(detail.getId());
                    reservation.setInstitutionId(detail.getInstitutionId());
                    reservation.setInstitutionName(detail.getInstitutionName());
                    reservation.setProductId(detail.getProductId());
                    reservation.setProductName(detail.getProductName());
                    reservation.setProductImage(detail.getImageFile());
                    reservation.setUid(detail.getUid());
                    reservation.setUserOrderId(detail.getUserOrderId());
                    reservation.setUserOrderDetailId(detail.getId());
                    reservation.setCardNo(detail.getCardNo());
                    reservation.setCardPassword(detail.getCardPassword());
                    reservation.setReserveStatus(Constant.RESERVATION_STATUS.NONE.value());

                    UserOrder userOrder = orderMap.get(detail.getUserOrderId());
                    if(userOrder == null){
                        userOrder = userOrderService.get(detail.getUserOrderId());
                        orderMap.put(detail.getUserOrderId(), userOrder);
                    }

                    int boughtDays = DateUtils.getIntervalOfDays(new Date(userOrder.getOrderTime()*1000), new Date());
                    int leftDays = 180 - boughtDays;
                    if(leftDays < 0 ){
                        reservation.setLeftDays("已过期");
                        reservation.setReserveStatus("1");
                    }else{
                        reservation.setReserveStatus("0");
                        if(leftDays > 30) {
                            reservation.setLeftDays("还剩" + leftDays/30 + "月");
                        }else{
                            reservation.setLeftDays("还剩" + 30 + "天");
                        }
                    }
                    reservation.setOrderNo(userOrder.getOrderNo());
                    reservationList.add(reservation);

                    lastId = detail.getId();
                }
            }else{
                lastId = -1L;
                reservationList = Collections.emptyList();
            }
        }else if ("1".equals(listType) || "2".equals(listType)){
            QueryFilter filter = new DynamicSQLFilterImpl();
            filter.addFilter("Q_uid_L_EQ", String.valueOf(uid));
            if("1".equals(listType)){
                //查询预约中和预约成功
                filter.addFilter("Q_reserveStatus_S_IN", Constant.RESERVATION_STATUS.RESERVING.value() + "," + Constant.RESERVATION_STATUS.SUCCESS.value());
            } else {
                //查询已使用和报告已出
                filter.addFilter("Q_reserveStatus_S_IN", Constant.RESERVATION_STATUS.USED.value() + "," +Constant.RESERVATION_STATUS.REPORT.value());
            }
            filter.setSortField("id", true);
            if(lastId > 0){
                filter.addFilter("Q_id_L_LT", String.valueOf(lastId));
            }
            reservationList = userReservationService.find(filter);
            if(reservationList != null && !reservationList.isEmpty()){
                lastId = reservationList.get(reservationList.size() - 1).getId();
            }else{
                lastId = -1L;
            }
        }else {
            return msgBean.failure("listType参数错误").returnMsg();
        }

        msgBean.put("lastId", lastId);
        msgBean.put("data", reservationList);
        return msgBean.returnMsg();
    }

    @ApiOperation(value="预约详情", httpMethod = "POST")
    @RequestMapping("/detail")
    @ApiResponses(value = {@ApiResponse(code = 200,message = "预约信息", response = UserReservation.class)})
    public @ResponseBody  Object reservationDetail(
            @ApiParam(value = "预约ID", required = true) @RequestParam(value = "reservationId") Long reservationId,
            @ApiIgnore HttpServletRequest request
    ){
        MsgBean msgBean = new MsgBean();
        Long uid = BaseVo.getUIDFromHeader(request);

        UserReservation reservation = userReservationService.get(reservationId);
        if(reservation == null){
            return msgBean.failure("预约信息不存在").returnMsg();
        }
        if(!reservation.getUid().equals(uid)){
            return msgBean.failure("非法操作").returnMsg();
        }
        msgBean.put("data", reservation);
        return msgBean.returnMsg();
    }

    @ApiOperation(value="取消预约", httpMethod = "POST")
    @RequestMapping("/cancel")
    @ApiResponses(value = {@ApiResponse(code = 200,message = "预约信息", response = UserReservation.class)})
    public @ResponseBody  Object reservationCancel(
            @ApiParam(value = "预约ID", required = true) @RequestParam(value = "reservationId") Long reservationId,
            @ApiIgnore HttpServletRequest request
    ){
        MsgBean msgBean = new MsgBean();
        Long uid = BaseVo.getUIDFromHeader(request);

        UserReservation reservation = userReservationService.get(reservationId);
        if(reservation == null){
            return msgBean.failure("预约信息不存在").returnMsg();
        }
        if(!reservation.getUid().equals(uid)){
            return msgBean.failure("非法操作").returnMsg();
        }
        String reserveType = reservation.getReserveType();
        String orderNo = reservation.getOrderNo();
        if(orderNo.startsWith("A")){
            UserOrder userOrder = userOrderService.getByOrderNo(orderNo);
            UserOrderDetail orderDetail = userOrderDetailService.getByCardNoAndPwd(reservation.getCardNo(), reservation.getCardPassword());
            if(orderDetail.getLeftCount()>0){
                return msgBean.failure("操作失败，请刷新预约列表后重试！").returnMsg();
            }
            orderDetail.setLeftCount(1);
            reservation.setReserveStatus(Constant.RESERVATION_STATUS.USER_CANCEL.value());
            userReservationService.update(reservation);
            userOrderDetailService.update(orderDetail);
        }else{
            OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
            if(!"1".equals(orderInfo.getBespeaked())){
                return msgBean.failure("操作失败，请刷新预约列表后重试！").returnMsg();
            }
            reservation.setReserveStatus(Constant.RESERVATION_STATUS.USER_CANCEL.value());
            orderInfo.setBespeaked("0");
            userReservationService.update(reservation);
            orderInfoService.update(orderInfo);
        }
        msgBean.put("data", reservation);
        return msgBean.returnMsg();
    }

    private ReserveProductVo toReserveProduct(OrderInfo orderInfo, String reserveType){
        long currTime = System.currentTimeMillis()/1000;
        ReserveProductVo vo = new ReserveProductVo();
        vo.setProductId(orderInfo.getIdProduct());
        vo.setProductName(orderInfo.getProductName());
        vo.setOrderNo(orderInfo.getOrderNo());
        vo.setCardNo(orderInfo.getCardNumber());
        vo.setReserveType(reserveType);
        vo.setStartDate(orderInfo.getStartDate() != null && orderInfo.getStartDate() > 0 ? orderInfo.getStartDate() : orderInfo.getOrderTime());
        vo.setEndDate(orderInfo.getEndDate() != null && orderInfo.getEndDate() > 0 ? orderInfo.getEndDate() : (orderInfo.getOrderTime() +  6 * 30 * 60 * 60));
        if(orderInfo.getOrderStatus() != OrderConstants.OrderStatus.Disabled.getStatusValue()
                && currTime > vo.getStartDate() && currTime < vo.getEndDate()
                && (orderInfo.getBespeaked() == null || !orderInfo.getBespeaked().equals("1"))) {
            vo.setStatus(1);
        }else{
            vo.setStatus(0);
        }
        return vo;
    }


    private MsgBean reserveByOrder(String orderNo, String cardNo, String reserveType, Long reservationId, HttpServletRequest request) {
        logger.info("#reserveByOrder#:reservationId:{},orderNo:{},reserveType:{}, cardNo:{}", reservationId, orderNo, reserveType, cardNo);
        MsgBean msgBean = new MsgBean();
        UserOrderDetail userOrderDetail = userOrderDetailService.getByCardNo(cardNo);
        if(userOrderDetail == null){
            msgBean.failure("订单信息有误");
            return msgBean;
        }
        if(reservationId == null && userOrderDetail.getLeftCount() == 0){
            msgBean.failure("订单中已无可预约的商品！");
            return msgBean;
        }
        List<Institution> institutions = productInstitutionService.getInstitutionByProductId(userOrderDetail.getProductId());
        if(institutions == null){
            institutions = new ArrayList<Institution>();
        }
        logger.info("#reserveByOrder#:institution count:{}", institutions.size());
        institutions.add(institutionService.get(userOrderDetail.getInstitutionId()));
        if(institutions.isEmpty()){
            msgBean.failure("无适用机构，请联系客服！");
            return msgBean;
        }
        ReserveOrderVo orderVo = new ReserveOrderVo();
        orderVo.setOrderNo(orderNo);
        orderVo.setCardNo(cardNo);
        orderVo.setReserveType(reserveType);

        Long uid = BaseVo.getUIDFromHeader(request);
        List<UserContact> contactList = userContactService.findByUID(uid);
        ToReserveVo vo = new ToReserveVo();
        vo.setUserContacts(contactList);
        vo.setOrderVo(orderVo);
        vo.addInstitution(institutions);
        vo.setReservationId(reservationId);
        msgBean.put("data", vo);
        return msgBean;
    }

    private MsgBean reserveByCardAndPassword(
            String orderNo,
            String cardNo,
            String reserveType,
            Long reservationId,
            HttpServletRequest request
    ) {
        logger.info("#reserveByCardAndPassword#:reservationId:{},orderNo:{},reserveType:{}, cardNo:{}", reservationId, orderNo, reserveType, cardNo);

        MsgBean msgBean = new MsgBean();
        Long uid = BaseVo.getUIDFromHeader(request);

        OrderInfo orderInfo = null;

        orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
        if(orderInfo == null) {
            orderInfo = orderInfoService.getByCardNumber(cardNo);
        }

        if(orderInfo == null){
            msgBean.failure("查找订单信息失败，请联系客服");
            return msgBean;
        }
        logger.info("#reserveByCardAndPassword#:orderInfo:{}", JSON.toJSONString(orderInfo));

        Long groupOrderId = null;
        List<Institution> institutionList = null;
        //如果是团单
        if(orderInfo.getGroupOrderId() != null && orderInfo.getGroupOrderId() != 0){
            groupOrderId = orderInfo.getGroupOrderId();
            //获取团单制定的机构和套餐对照
            List<GroupOrderProduct> groupOrderProductList = groupOrderProductService.getByGroupOrderId(groupOrderId);
            List<Long> productIdList = new ArrayList<Long>(groupOrderProductList.size());
            for(GroupOrderProduct groupOrderProduct : groupOrderProductList){
                productIdList.add(groupOrderProduct.getIdProduct());
            }
            //根据团单的商品IDs和商品名称，获取institutionIds
            String productIds = Joiner.on(",").join(productIdList);
            logger.info("#reserveByCardAndPassword#:productIds:{}", productIds);
            List<Product> productList = productService.getInstitutionIdAndProductIdsByProductIds(productIds, orderInfo.getProductName());
            List<Long> institutionIdList = new ArrayList<Long>();
            for(Product product : productList){
                institutionIdList.add(product.getIdInstitution());
            }
            String institutionIds = Joiner.on(",").join(institutionIdList);
            logger.info("#reserveByCardAndPassword#1:institutionIds:{}", institutionIds);
            //根据机构IDs，获取机构的信息
            institutionList = institutionService.getInstitutionByIds(institutionIds);
            //都没有的情况，补充机构信息
            if(institutionList == null){
                institutionList = new ArrayList<Institution>();
                //订单中机构ID存在，取之
                if(orderInfo.getIdInstitution() != null && orderInfo.getIdInstitution() != 0){
                    institutionList.add(institutionService.get(orderInfo.getIdInstitution()));
                }else{
                    //否则，根据机构名称取之
                    institutionList.addAll(institutionService.getBaseInfoByName(orderInfo.getInstitutionName()));
                }

            }
        }else{
            //如果不是团单
            Long productId = orderInfo.getIdProduct();
            institutionList = productInstitutionService.getInstitutionByProductId(productId);
            if(institutionList == null && orderInfo.getIdInstitution() != null && orderInfo.getIdInstitution() != 0){
                institutionList = new ArrayList<Institution>();
                institutionList.add(institutionService.get(orderInfo.getIdInstitution()));
            }
            logger.info("#reserveByCardAndPassword#2:institutionList:{}", JSON.toJSONString(institutionList));
        }
        if(institutionList == null || institutionList.isEmpty()){
            msgBean.failure("无适用机构，请联系客服！");
            return msgBean;
        }
        ReserveOrderVo orderVo = new ReserveOrderVo();
        orderVo.setOrderNo(orderNo);
        orderVo.setCardNo(cardNo);
        orderVo.setReserveType(reserveType);
        orderVo.setIdentify(orderInfo.getIdCard());
        orderVo.setName(orderInfo.getGroupName());

        List<UserContact> contactList = userContactService.findByUID(uid);
        ToReserveVo vo = new ToReserveVo();
        vo.setUserContacts(contactList);
        vo.setOrderVo(orderVo);
        vo.addInstitution(institutionList);
        vo.setReservationId(reservationId);
        msgBean.put("data", vo);
        return msgBean;
    }
}
